package cn.oldfeel.spark.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketIDFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Registration;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.ReportedData;
import org.jivesoftware.smackx.ReportedData.Row;
import org.jivesoftware.smackx.search.UserSearchManager;

import android.os.Handler;
import android.os.Message;
import android.util.Log;
import cn.oldfeel.spark.config.UserInfo;

/**
 * 单例模式创建一个唯一的xmpp连接.
 * 
 * @author oldfeel
 * 
 */
public class XMPPHelper {
	/** openfire服务器ip */
	public static final String IP = "192.168.10.233";
	/** 连接失败 */
	public static final int CONNECT_FAIL = 0;
	/** 连接成功 */
	public static final int CONNECT_SUCCESS = 1;
	/** 登录成功 */
	public static final int LOGIN_SUCCESS = 2;
	/** 登录失败 */
	public static final int LOGIN_FAIL = 3;
	/** 注册失败,服务器没有响应 */
	public static final int REG_NO_RESPONSE = 4;
	/** 注册成功 */
	public static final int REG_SUCCESS = 5;
	/** 注册失败,错误 409 */
	public static final int REG_FAIL_409 = 6;
	/** 注册失败,其他错误 */
	public static final int REG_FAIL_OTHER = 7;
	/** 修改密码成功 */
	public static final int CHANGE_PASSWORD_SUCCESS = 8;
	/** 修改密码失败 */
	public static final int CHANGE_PASSWORD_FAIL = 9;
	/** 删除帐号成功 */
	public static final int DELETE_SUCCESS = 10;
	/** 删除帐号失败 */
	public static final int DELETE_FAIL = 11;
	/** 状态,离线 */
	public static final int STATUS_UNAVAILABLE = 12;
	/** 状态,隐身 */
	public static final int STATUS_NOT_AVAILABLE = 13;
	/** 状态,离开 */
	public static final int STATUS_AWAY = 14;
	/** 状态,忙碌 */
	public static final int STATUS_DND = 15;
	/** 状态,Q我吧 */
	public static final int STATUS_CHAT = 16;
	/** 状态,在线 */
	public static final int STATUS_AVAILABLE = 17;
	/** 添加好友成功 */
	public static final int ADD_SUCCESS = 18;
	/** 添加好友失败 */
	public static final int ADD_FAIL = 19;
	private static XMPPHelper helper;
	private static XMPPConnection connection;

	/**
	 * 初始化一个xmpp连接.
	 * 
	 * @return
	 */
	public static XMPPHelper getInstance() {
		if (helper == null) {
			helper = new XMPPHelper();
		}
		if (connection == null) {
			XMPPUtil.configure(ProviderManager.getInstance());
			ConnectionConfiguration config = new ConnectionConfiguration(IP,
					5222);
			// config.setSendPresence(true);
			// config.setReconnectionAllowed(true);
			config.setSASLAuthenticationEnabled(false);
			// config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);
			// File file = new File("/mnt/sdcard/security/");
			// file.mkdirs();
			// config.setTruststorePath("/mnt/sdcard/security/cacerts.bks");
			// config.setTruststorePassword("123456");
			// config.setTruststoreType("bks");
			// config.setSASLAuthenticationEnabled(true);
			connection = new XMPPConnection(config);
		}
		return helper;
	}

	/**
	 * 测试连接xmpp服务器是否成功
	 * 
	 * @param handler
	 *            连接后发送消息,0为连接失败,1为连接成功
	 * @param userInfo
	 */
	public void connect(final Handler handler, final UserInfo userInfo) {
		new Thread() {
			@Override
			public void run() {
				super.run();
				try {
					connection.connect();
					handler.sendEmptyMessage(CONNECT_SUCCESS); // 连接成功.发送1
					// 如果保存的帐号不为空,则自动登录
					if (userInfo.getName().length() != 0) {
						connection.login(userInfo.getName(),
								userInfo.getPassword());
						handler.sendEmptyMessage(LOGIN_SUCCESS);
					}
				} catch (XMPPException e) {
					e.printStackTrace();
					handler.sendEmptyMessage(CONNECT_FAIL); // 连接失败.发送0
				}
			}
		}.start();
	}

	/**
	 * 登录
	 * 
	 * @param handler
	 * @param account
	 * @param password
	 */
	public void login(final Handler handler, final String account,
			final String password) {
		new Thread() {
			@Override
			public void run() {
				super.run();
				try {
					if (connection == null || !connection.isConnected()) {
						handler.sendEmptyMessage(CONNECT_FAIL);
						return;
					}
					connection.login(account, password);
					handler.sendEmptyMessage(LOGIN_SUCCESS);
				} catch (XMPPException e) {
					e.printStackTrace();
					handler.sendEmptyMessage(LOGIN_FAIL);
				}
			}
		}.start();

	}

	/**
	 * 注册
	 * 
	 * @param handler
	 * @param account
	 * @param password
	 */
	public void regist(final Handler handler, final String account,
			final String password) {
		new Thread() {
			public void run() {
				if (connection == null || !connection.isConnected()) {
					handler.sendEmptyMessage(CONNECT_FAIL);
					return;
				}
				Registration registration = new Registration();
				registration.setType(IQ.Type.SET);
				registration.setTo(connection.getServiceName());
				registration.setUsername(account);
				registration.setPassword(password);
				registration.addAttribute("android", "created by android");
				PacketFilter filter = new AndFilter(new PacketIDFilter(
						registration.getPacketID()), new PacketTypeFilter(
						IQ.class));
				PacketCollector collector = connection
						.createPacketCollector(filter);
				connection.sendPacket(registration);
				IQ result = (IQ) collector.nextResult(SmackConfiguration
						.getPacketReplyTimeout());
				collector.cancel(); // 停止请求
				if (result == null) {
					handler.sendEmptyMessage(REG_NO_RESPONSE);
				} else if (result.getType() == IQ.Type.RESULT) {
					handler.sendEmptyMessage(REG_SUCCESS);
					try {
						// 登录
						connection.login(account, password);
					} catch (XMPPException e) {
						e.printStackTrace();
					}
				} else {
					if (result.getError().toString()
							.equalsIgnoreCase("conflict(409)")) {
						handler.sendEmptyMessage(REG_FAIL_409);
					} else {
						handler.sendEmptyMessage(REG_FAIL_OTHER);
					}
					LogUtil.showLog("注册失败,错误:" + result.getError());
				}
			};
		}.start();
	}

	/**
	 * 修改密码
	 * 
	 * @param handler
	 * @param newPassword
	 */
	public static void changePassword(final Handler handler,
			final String newPassword) {
		new Thread() {
			@Override
			public void run() {
				super.run();
				if (connection == null || !connection.isConnected()) {
					handler.sendEmptyMessage(CONNECT_FAIL);
					return;
				}
				try {
					connection.getAccountManager().changePassword(newPassword);
					handler.sendEmptyMessage(CHANGE_PASSWORD_SUCCESS);
				} catch (XMPPException e) {
					e.printStackTrace();
					handler.sendEmptyMessage(CHANGE_PASSWORD_FAIL);
				}
			}
		}.start();
	}

	/**
	 * 设置状态
	 * 
	 * @param handler
	 * @param which
	 *            0为在线,1为Q我吧,2为忙碌,3为离开,4为隐身,5为离线
	 */
	public void setStatus(final Handler handler, final int which) {
		new Thread() {
			public void run() {
				if (connection == null || !connection.isConnected()) {
					handler.sendEmptyMessage(CONNECT_FAIL);
					return;
				}
				Presence presence;
				switch (which) {
				case 0:
					presence = new Presence(Presence.Type.available);
					connection.sendPacket(presence);
					Log.v("state", "设置在线");
					handler.sendEmptyMessage(STATUS_AVAILABLE);
					break;
				case 1:
					presence = new Presence(Presence.Type.available);
					presence.setMode(Presence.Mode.chat);
					connection.sendPacket(presence);
					Log.v("state", "设置Q我吧");
					System.out.println(presence.toXML());
					handler.sendEmptyMessage(STATUS_CHAT);
					break;
				case 2:
					presence = new Presence(Presence.Type.available);
					presence.setMode(Presence.Mode.dnd);
					connection.sendPacket(presence);
					Log.v("state", "设置忙碌");
					System.out.println(presence.toXML());
					handler.sendEmptyMessage(STATUS_DND);
					break;
				case 3:
					presence = new Presence(Presence.Type.available);
					presence.setMode(Presence.Mode.away);
					connection.sendPacket(presence);
					Log.v("state", "设置离开");
					System.out.println(presence.toXML());
					handler.sendEmptyMessage(STATUS_AWAY);
					break;
				case 4:
					Roster roster = connection.getRoster();
					Collection<RosterEntry> entries = roster.getEntries();
					for (RosterEntry entry : entries) {
						presence = new Presence(Presence.Type.unavailable);
						presence.setPacketID(Packet.ID_NOT_AVAILABLE);
						presence.setFrom(connection.getUser());
						presence.setTo(entry.getUser());
						connection.sendPacket(presence);
						System.out.println(presence.toXML());
					}
					// 向同一用户的其他客户端发送隐身状态
					presence = new Presence(Presence.Type.unavailable);
					presence.setPacketID(Packet.ID_NOT_AVAILABLE);
					presence.setFrom(connection.getUser());
					presence.setTo(StringUtils.parseBareAddress(connection
							.getUser()));
					connection.sendPacket(presence);
					Log.v("state", "设置隐身");
					handler.sendEmptyMessage(STATUS_NOT_AVAILABLE);
					break;
				case 5:
					presence = new Presence(Presence.Type.unavailable);
					connection.sendPacket(presence);
					Log.v("state", "设置离线");
					handler.sendEmptyMessage(STATUS_UNAVAILABLE);
					break;
				default:
					break;
				}
			};
		}.start();
	}

	/**
	 * 获取好友列表
	 * 
	 * @param handler
	 */
	public void getFriendList(final Handler handler) {
		new Thread() {
			public void run() {
				Roster roster = connection.getRoster();
				Collection<RosterEntry> it = roster.getEntries();
				ArrayList<String> friends = new ArrayList<String>();
				for (RosterEntry rosterEnter : it) {
					if (rosterEnter.getType().name().equals("both")) { // 双向好友
						friends.add(rosterEnter.getUser());
					}
				}

				if (friends.size() == 0) {
					friends.add("暂无好友");
				}
				Message msg = new Message();
				msg.obj = friends;
				handler.sendMessage(msg);
			};
		}.start();
	}

	/**
	 * 添加好友
	 * 
	 * @param handler
	 * @param name
	 */
	public void addFriend(final Handler handler, final String name) {
		new Thread() {
			@Override
			public void run() {
				super.run();
				try {
					// connection.getRoster().createEntry(name, null,
					// new String[] { "friends" });
					UserSearchManager search = new UserSearchManager(connection);
					Form searchForm = search.getSearchForm("search."
							+ connection.getServiceName());
					Form answerForm = searchForm.createAnswerForm();
					answerForm.setAnswer("Username", true);
					answerForm.setAnswer("search", name);
					ReportedData data = search.getSearchResults(answerForm,
							"search." + connection.getServiceName());
					Iterator<Row> iterator = data.getRows();
					while (iterator.hasNext()) {
						Row row = iterator.next();
						String queryResult = row.getValues("Username").next()
								.toString();
					}
					handler.sendEmptyMessage(ADD_SUCCESS);
				} catch (XMPPException e) {
					e.printStackTrace();
					handler.sendEmptyMessage(ADD_FAIL);
				}
			}
		}.start();
	}

	/**
	 * 断开连接
	 */
	public void disConnect() {
		connection.disconnect();
	}

	public XMPPConnection getConnect() {
		return connection;
	}
}
